package study.week05.gateway.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import study.week05.gateway.filter.CustomHttpFilter;
import study.week05.gateway.inbound.InboundHandler;
import study.week05.gateway.netty.NettyHttpServer;
import study.week05.gateway.netty.ServerContainer;
import study.week05.gateway.outbound.OutboundHandler;
import study.week05.gateway.outbound.JmsHandler;
import study.week05.gateway.router.CustomRouter;

import java.util.Arrays;
import java.util.concurrent.*;

@EnableConfigurationProperties({DemoProperties.class})
@Configuration
public class GatewayConfig {

    @Autowired
    private DemoProperties properties;

    @Bean
    public ExecutorService proxyService(){
        int cores = Runtime.getRuntime().availableProcessors();
        long keepAliveTime = 1000;
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();//.DiscardPolicy();
        return  new ThreadPoolExecutor(cores, cores,
                keepAliveTime, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(properties.queueSize), handler);
    }
    @Bean
    public InboundHandler inboundHandler(OutboundHandler outboundHandler ){
        return new InboundHandler(outboundHandler);
    }
    @Bean
    public JmsHandler jmsHandler(JmsTemplate jmsTemplate){
        return new JmsHandler(jmsTemplate);
    }
    @Bean
    public OutboundHandler outboundHandler( JmsHandler jmsHandler, ExecutorService proxyService) {
        return new OutboundHandler(proxyService,jmsHandler);
    }
    @Bean
    public NettyHttpServer nettyHttpServer( InboundHandler inboundHandler){
        return new NettyHttpServer(properties.getPort(), inboundHandler);
    }

    @Bean
    public ServerContainer serverList(){
       return new ServerContainer(Arrays.asList(properties.getServerList().split(",")));
    }

    @Bean
    public CustomHttpFilter[] filterChain() throws Exception {
        String[] cls = properties.getFilters().split(",");
        CustomHttpFilter[] res = new CustomHttpFilter[cls.length];
        for (int i = 0; i < cls.length; i++) {
            res[i] = (CustomHttpFilter) Class.forName(cls[i]).newInstance();
        }
        return res;
    }

    @Bean
    public  CustomRouter router() throws Exception {
       return (CustomRouter) Class.forName(properties.getRoute()).newInstance();
    }
}
